using Microsoft.AspNetCore.Mvc;
using RAG.Application.Dtos.Rag;
using RAG.Application.Services.Interfaces;

namespace RAG.Api.Controllers;

/// <summary>
/// RAG问答控制器
/// </summary>
[ApiController]
[Route("api/[controller]")]
public class RagController : ControllerBase
{
    private readonly IRagQuestionAnswerService _ragService;
    private readonly ILogger<RagController> _logger;
    private readonly RAG.Domain.Repositories.IKnowledgeBaseRepository _knowledgeRepo;

    public RagController(IRagQuestionAnswerService ragService,
        RAG.Domain.Repositories.IKnowledgeBaseRepository knowledgeRepo,
        ILogger<RagController> logger)
    {
        _ragService = ragService;
        _knowledgeRepo = knowledgeRepo;
        _logger = logger;
    }

    /// <summary>
    /// 基于知识库的智能问答
    /// </summary>
    /// <param name="request">问答请求</param>
    /// <returns>AI回答</returns>
    [HttpPost("ask")]
    public async Task<ActionResult<RagQuestionAnswerResponseDto>> AskQuestion([FromBody] RagQuestionAnswerRequestDto request)
    {
        try
        {
            if (string.IsNullOrWhiteSpace(request.Question))
            {
                return BadRequest("问题不能为空");
            }

            _logger.LogInformation($"收到问答请求: {request.Question}");

            var response = await _ragService.AskQuestionAsync(request);

            _logger.LogInformation($"问答处理完成，耗时: {response.ProcessingTimeMs}ms");

            return Ok(response);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "处理问答请求时发生错误");
            return StatusCode(500, "服务器内部错误");
        }
    }

    /// <summary>
    /// 获取知识库中的相似内容（调试用）
    /// </summary>
    /// <param name="question">问题</param>
    /// <param name="limit">返回数量限制</param>
    /// <param name="threshold">相似度阈值</param>
    /// <returns>相似内容列表</returns>
    [HttpGet("similar")]
    public async Task<ActionResult<List<SimilarKnowledgeDto>>> GetSimilarKnowledge(
        [FromQuery] string question,
        [FromQuery] int limit = 5,
        [FromQuery] double threshold = 0.7)
    {
        try
        {
            if (string.IsNullOrWhiteSpace(question))
            {
                return BadRequest("问题不能为空");
            }

            var similarKnowledge = await _ragService.GetSimilarKnowledgeAsync(question, limit, threshold);
            return Ok(similarKnowledge);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取相似知识时发生错误");
            return StatusCode(500, "服务器内部错误");
        }
    }

    /// <summary>
    /// 上传知识内容到知识库
    /// </summary>
    /// <param name="request">知识上传请求</param>
    /// <returns>上传结果</returns>
    [HttpPost("upload-knowledge")]
    public async Task<ActionResult<KnowledgeUploadResponseDto>> UploadKnowledge([FromBody] KnowledgeUploadRequestDto request)
    {
        try
        {
            if (string.IsNullOrWhiteSpace(request.Title) || string.IsNullOrWhiteSpace(request.Content))
            {
                return BadRequest("标题和内容不能为空");
            }

            if (request.UserId == Guid.Empty)
            {
                return BadRequest("用户ID不能为空");
            }

            _logger.LogInformation($"收到知识上传请求: {request.Title}");

            var response = await _ragService.UploadKnowledgeAsync(request);

            if (response.Success)
            {
                _logger.LogInformation($"知识上传成功: {request.Title}");
                return Ok(response);
            }
            else
            {
                _logger.LogWarning($"知识上传失败: {response.Message}");
                return BadRequest(response);
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "上传知识时发生错误");
            return StatusCode(500, "服务器内部错误");
        }
    }

    /// <summary>
    /// 上传多模态知识内容（图片+文本）
    /// </summary>
    /// <param name="request">多模态知识上传请求</param>
    /// <returns>上传结果</returns>
    [HttpPost("upload-multimodal-knowledge")]
    public async Task<ActionResult<KnowledgeUploadResponseDto>> UploadMultimodalKnowledge([FromBody] MultimodalKnowledgeUploadRequestDto request)
    {
        try
        {
            if (request == null)
            {
                return BadRequest("请求不能为空");
            }

            if (string.IsNullOrWhiteSpace(request.Title))
            {
                return BadRequest("标题不能为空");
            }

            if (string.IsNullOrWhiteSpace(request.ImageBase64) && string.IsNullOrWhiteSpace(request.ImageUrl))
            {
                return BadRequest("必须提供图片数据（ImageBase64或ImageUrl）");
            }

            _logger.LogInformation($"收到多模态知识上传请求: {request.Title}");

            var result = await _ragService.UploadMultimodalKnowledgeAsync(request);

            if (result.Success)
            {
                _logger.LogInformation($"多模态知识上传成功: {request.Title}");
                return Ok(result);
            }
            else
            {
                _logger.LogWarning($"多模态知识上传失败: {result.Message}");
                return BadRequest(result.Message);
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "上传多模态知识时发生错误");
            return StatusCode(500, "服务器内部错误");
        }
    }

    /// <summary>
    /// 批量上传知识内容
    /// </summary>
    /// <param name="requests">批量知识上传请求</param>
    /// <returns>批量上传结果</returns>
    [HttpPost("batch-upload-knowledge")]
    public async Task<ActionResult<List<KnowledgeUploadResponseDto>>> BatchUploadKnowledge([FromBody] List<KnowledgeUploadRequestDto> requests)
    {
        try
        {
            if (requests == null || !requests.Any())
            {
                return BadRequest("上传列表不能为空");
            }

            _logger.LogInformation($"收到批量知识上传请求，数量: {requests.Count}");

            var responses = new List<KnowledgeUploadResponseDto>();

            foreach (var request in requests)
            {
                if (string.IsNullOrWhiteSpace(request.Title) || string.IsNullOrWhiteSpace(request.Content))
                {
                    responses.Add(new KnowledgeUploadResponseDto
                    {
                        Success = false,
                        Message = "标题和内容不能为空"
                    });
                    continue;
                }

                if (request.UserId == Guid.Empty)
                {
                    responses.Add(new KnowledgeUploadResponseDto
                    {
                        Success = false,
                        Message = "用户ID不能为空"
                    });
                    continue;
                }

                var response = await _ragService.UploadKnowledgeAsync(request);
                responses.Add(response);
            }

            var successCount = responses.Count(r => r.Success);
            _logger.LogInformation($"批量知识上传完成，成功: {successCount}/{requests.Count}");

            return Ok(responses);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "批量上传知识时发生错误");
            return StatusCode(500, "服务器内部错误");
        }
    }

    /// <summary>
    /// 健康检查
    /// </summary>
    /// <returns>服务状态</returns>
    [HttpGet("health")]
    public ActionResult<object> HealthCheck()
    {
        return Ok(new
        {
            Status = "Healthy",
            Service = "RAG Question Answer Service",
            Timestamp = DateTime.UtcNow,
            Version = "1.0.0"
        });
    }

    /// <summary>
    /// 调试：查看知识库数据统计
    /// </summary>
    /// <returns>知识库统计信息</returns>
    [HttpGet("debug/knowledge-count")]
    public async Task<ActionResult<object>> GetKnowledgeCount()
    {
        try
        {
            var total = await _knowledgeRepo.CountAllAsync();
            var byEmbedding = await _knowledgeRepo.CountByEmbeddingTypeAsync();
            return Ok(new
            {
                TotalCount = total,
                ByEmbeddingType = byEmbedding,
                Message = "知识库记录统计（直接计数）",
                Timestamp = DateTime.UtcNow
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取知识库统计信息时发生错误");
            return StatusCode(500, new { Error = "获取统计信息失败", Message = ex.Message });
        }
    }

    /// <summary>
    /// 更详细的知识库统计（含最近记录）
    /// </summary>
    [HttpGet("debug/knowledge-stats")]
    public async Task<ActionResult<object>> GetKnowledgeStats()
    {
        try
        {
            var total = await _knowledgeRepo.CountAllAsync();
            var byEmbedding = await _knowledgeRepo.CountByEmbeddingTypeAsync();

            // 取最近 5 条（直接用相似接口不准确，改为标题模糊匹配 or 简单取全部再排序 - 这里简化假设数量不大）
            // 若后续需优化，可在仓储添加获取最新记录方法
            var recent = (await _knowledgeRepo.GetAllAsync())
                .OrderByDescending(k => k.CreatedAt)
                .Take(5)
                .Select(k => new { k.Id, k.Title, k.EmbeddingType, k.CreatedAt })
                .ToList();

            return Ok(new
            {
                TotalCount = total,
                ByEmbeddingType = byEmbedding,
                Recent = recent,
                Message = "知识库详细统计",
                Timestamp = DateTime.UtcNow
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取知识库详细统计信息时发生错误");
            return StatusCode(500, new { Error = "获取统计信息失败", Message = ex.Message });
        }
    }

    /// <summary>
    /// 清理知识库（删除所有MockEmbeddingService生成的随机向量数据）
    /// </summary>
    [HttpPost("cleanup")]
    public async Task<ActionResult> CleanupKnowledgeBase()
    {
        try
        {
            _logger.LogInformation("开始清理知识库...");

            var result = await _ragService.CleanupKnowledgeBaseAsync();

            _logger.LogInformation($"知识库清理完成，删除了 {result.DeletedCount} 条记录");

            return Ok(new
            {
                Message = "知识库清理完成",
                DeletedCount = result.DeletedCount,
                Timestamp = DateTime.UtcNow
            });
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "清理知识库时发生错误");
            return StatusCode(500, new { Error = "清理知识库失败", Message = ex.Message });
        }
    }
}
